using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using EzDeploy.Resources;

namespace EzDeploy.Core
{
    public class ResolveAssemblyReferenceTask : IResolveAssemblyReferenceTask
    {
        private readonly IAssemblyReferenceResolver _resolver;

        public ResolveAssemblyReferenceTask(IAssemblyReferenceResolver resolver)
        {
            _resolver = resolver;
        }

        public void Resolve(Project project)
        {
            if (!string.IsNullOrEmpty(project.AssemblyFile))
            {
                List<AssemblyInfo> assemblies = null;

                var task = Task.Factory.StartNew(() =>
                {
                    _resolver.Reset();
                    assemblies = _resolver.Resolve(project, new AssemblyResolver(Path.GetDirectoryName(project.AssemblyFile)));
                });

                var waiter = task.GetAwaiter();

                waiter.OnCompleted(() =>
                {
                    _resolver.Reset();

                    if (task.IsFaulted)
                    {
                        string errorMessage = string.Empty;
                        if (task.Exception != null)
                        {
                            var ex = task.Exception.GetBaseException();
                            if (ex is BadImageFormatException)
                                errorMessage = string.Format(MessageResource.FileIsNotNETAssemblyFmt, Path.GetFileName(project.AssemblyFile), Environment.NewLine);
                            else
                                errorMessage = ex.Message;
                        }

                        GC.Collect();

                        this.OnComplete(new Result(ResultType.Error, errorMessage));

                        return;
                    }

                    if (assemblies != null)
                    {
                        if (assemblies.Count == 0)
                        {
                            string errorMessage = string.Format(MessageResource.MainAssemblyNotFoundFmt, Path.GetFileName(project.AssemblyFile));
                            this.OnComplete(new Result(ResultType.Error, errorMessage));
                        }
                        else
                        {
                            var deployGridItems = new List<DeployGridItem>();
                            foreach (var assembly in assemblies)
                                deployGridItems.Add(new DeployGridItem(assembly));

                            GC.Collect();

                            this.OnComplete(new Result(ResultType.Success, deployGridItems, string.Empty));
                        }
                    }
                });
            }
        }

        protected virtual void OnComplete(Result args)
        {
            var handler = Complete;
            if (handler != null) handler(this, args);
        }

        public event TaskExecutedEventHandler Complete;
    }
}
